第二十章 ESP32的空中升级(OTA)

您所在的位置:网站首页 esp32 MQTT ota Ubuntu 第二十章 ESP32的空中升级(OTA)

第二十章 ESP32的空中升级(OTA)

2023-12-13 04:27| 来源: 网络整理| 查看: 265

static void ota_example_task(void *pvParameter)

{

    esp_err_t err;

    /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */

    esp_ota_handle_t update_handle = 0 ;

    const esp_partition_t *update_partition = NULL;

 

    ESP_LOGI(TAG, "Starting OTA example...");

    //获取OTA app存放的位置

    const esp_partition_t *configured = esp_ota_get_boot_partition();

    //获取当前系统执行的固件所在的Flash分区

    const esp_partition_t *running = esp_ota_get_running_partition();

 

    if (configured != running) {

        ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x",

                 configured->address, running->address);

        ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)");

    }

    ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",

             running->type, running->subtype, running->address);

 

    //等待wifi连上后进行OTA,项目中可以使升级命令进入OTA

    xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,

                        false, true, portMAX_DELAY);

    ESP_LOGI(TAG, "Connect to Wifi ! Start to Connect to Server....");

 

    //连http服务器

    if (connect_to_http_server()) {

        ESP_LOGI(TAG, "Connected to http server");

    } else {

        ESP_LOGE(TAG, "Connect to http server failed!");

        task_fatal_error();

    }

 

    //组http包发送

    const char *GET_FORMAT =

        "GET %s HTTP/1.0\r\n"

        "Host: %s:%s\r\n"

        "User-Agent: esp-idf/1.0 esp32\r\n\r\n";

 

    char *http_request = NULL;

    int get_len = asprintf(&http_request, GET_FORMAT, EXAMPLE_FILENAME, EXAMPLE_SERVER_IP, EXAMPLE_SERVER_PORT);

    if (get_len < 0) {

        ESP_LOGE(TAG, "Failed to allocate memory for GET request buffer");

        task_fatal_error();

    }

    int res = send(socket_id, http_request, get_len, 0);

    free(http_request);

    if (res < 0) {

        ESP_LOGE(TAG, "Send GET request to server failed");

        task_fatal_error();

    } else {

        ESP_LOGI(TAG, "Send GET request to server succeeded");

    }

 

    //获取当前系统下一个(紧邻当前使用的OTA_X分区)可用于烧录升级固件的Flash分区

    update_partition = esp_ota_get_next_update_partition(NULL);

    ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",

             update_partition->subtype, update_partition->address);

    assert(update_partition != NULL);

    //OTA写开始

    err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);

    if (err != ESP_OK) {

        ESP_LOGE(TAG, "esp_ota_begin failed, error=%d", err);

        task_fatal_error();

    }

    ESP_LOGI(TAG, "esp_ota_begin succeeded");

 

    bool resp_body_start = false, flag = true;

    //接收完成

    while (flag) {

        memset(text, 0, TEXT_BUFFSIZE);

        memset(ota_write_data, 0, BUFFSIZE);

        //接收http包

        int buff_len = recv(socket_id, text, TEXT_BUFFSIZE, 0);

        if (buff_len < 0) { //包异常

            ESP_LOGE(TAG, "Error: receive data error! errno=%d", errno);

            task_fatal_error();

        } else if (buff_len > 0 && !resp_body_start) { //包头

            memcpy(ota_write_data, text, buff_len);

            resp_body_start = read_past_http_header(text, buff_len, update_handle);

        } else if (buff_len > 0 && resp_body_start) { //数据段包

            memcpy(ota_write_data, text, buff_len);

            //写flash

            err = esp_ota_write( update_handle, (const void *)ota_write_data, buff_len);

            if (err != ESP_OK) {

                ESP_LOGE(TAG, "Error: esp_ota_write failed! err=0x%x", err);

                task_fatal_error();

            }

            binary_file_length += buff_len;

            ESP_LOGI(TAG, "Have written image length %d", binary_file_length);

        } else if (buff_len == 0) {  //结束包

            flag = false;

            ESP_LOGI(TAG, "Connection closed, all packets received");

            close(socket_id);

        } else {//未知错误

            ESP_LOGE(TAG, "Unexpected recv result");

        }

    }

 

    ESP_LOGI(TAG, "Total Write binary data length : %d", binary_file_length);

    //OTA写结束

    if (esp_ota_end(update_handle) != ESP_OK) {

        ESP_LOGE(TAG, "esp_ota_end failed!");

        task_fatal_error();

    }

    //升级完成更新OTA data区数据,重启时根据OTA data区数据到Flash分区加载执行目标(新)固件

    err = esp_ota_set_boot_partition(update_partition);

    if (err != ESP_OK) {

        ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%x", err);

        task_fatal_error();

    }

    ESP_LOGI(TAG, "Prepare to restart system!");

    esp_restart();

    return ;

}



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3